package com.zzyy.study.review;

import com.zzyy.study.review.container.PayTypeParseStrategyContainer;
import com.zzyy.study.review.enums.PayTypeStrEnum;
import com.zzyy.study.review.strategy.CCBPayTypeParseStrategy;
import com.zzyy.study.review.strategy.PayTypeParseContext;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;

/**
 * 代码优化是初心，过度设计是邪教
 * @auther zzyy
 * @create 2024-06-23 10:37
 */
public class OverDesignDemo
{

    //初心
    public Integer PayServiceImpl(String payTypeStr)
    {
        //判断有没有，空不空
        if(payTypeStr == null || payTypeStr.equals(""))
        {
            return null;
        }
        //返回多少
        if(payTypeStr.equals("CCB"))
        {
            return 1;
        }


        return null;
    }


    public Integer parsePayType(String payTypeStr)
    {
        if(payTypeStr == null || payTypeStr.equals(""))
        {
            return null;
        }

        if(payTypeStr.equals("CCB"))
        {
            return 1;
        }

        return null;
    }

    /**
     * V1
     * 1.1 StringUtils.isBlank替换，记得区分StringUtils.isBlank和StringUtils.isEmpty
     * 1.2 equals判定的时候，常量写前面避免空指针
     * @param payTypeStr
     * @return
     */
    public Integer parsePayTypeV1(String payTypeStr)
    {
        if(StringUtils.isBlank(payTypeStr))
        {
            return null;
        }

        if("CCB".equals(payTypeStr))
        {
            return 1;
        }

        return null;
    }

    /**
     * V2
     * 定义常量替代魔法值，避免多处使用后出现遗漏
     * @param payTypeStr
     * @return
     */
    private static final String  CCB_PAY_TYPE_STR = "CCB";
    private static final Integer CCB_PAY_TYPE_INT = 1;
    public Integer parsePayTypeV2(String payTypeStr)
    {

        if(StringUtils.isBlank(payTypeStr))
        {
            return null;
        }

        if(CCB_PAY_TYPE_STR.equals(payTypeStr))
        {
            return CCB_PAY_TYPE_INT;
        }
        return null;
    }

    /**
     * V3
     * 3.1 截止到V3版，if(StringUtils.isBlank(payTypeStr))  return null; 可以省略不要
     * 3.2 只需要把常量对应写好即可，非空判定可以去掉，要么命中正确值要么返回null
     * @param payTypeStr
     * @return
     */
    public Integer parsePayTypeV3(String payTypeStr)
    {
        if(CCB_PAY_TYPE_STR.equals(payTypeStr))
        {
            return CCB_PAY_TYPE_INT;
        }
        return null;
    }

    /**
     * V4
     * 4.1 三目运算
     * 4.2 只需要把常量对应写好即可，非空判定可以去掉，要么命中正确值要么返回null
     *
     * 思考，当我只有
     * @param payTypeStr
     * @return
     */
    public Integer parsePayTypeV4(String payTypeStr)
    {
        /*
        if(CCB_PAY_TYPE_STR.equals(payTypeStr))
        {
            return CCB_PAY_TYPE_INT;
        }
        return null;
        */

        //4.1
        //return CCB_PAY_TYPE_STR.equals(payTypeStr) ? CCB_PAY_TYPE_INT : null;


        //4.2
        return Optional.ofNullable(payTypeStr)
                .filter(CCB_PAY_TYPE_STR::equals)
                .map(o -> CCB_PAY_TYPE_INT)
                .orElse(null);
    }





    /**
     * V5
     * 截止到V4版本时，代码只有一行的话，这个存在性就可以讨论了,
     * 只有一行的话，干脆回到原业务方法处理，防止代码来回跳转防止阅读障碍
     * @param payTypeStr
     */
    public void PayServiceImplV5(String payTypeStr)
    {
        // 主干业务逻辑
        Integer retValue1 = CCB_PAY_TYPE_STR.equals(payTypeStr) ? CCB_PAY_TYPE_INT : null;
        Integer retValue2 = Optional.ofNullable(payTypeStr).filter(CCB_PAY_TYPE_STR::equals).map(o -> CCB_PAY_TYPE_INT).orElse(null);
    }











    /**====================================================
     * 方法是否独立出来？
     * 1    是否还有其它扩展需求，截止到上面的V5版，只有一个分支
     * 2    虽然一个分支但是和上下文有关系
     * 3    虽然一个分支但是代表的意义可能会变更，比如CCB = 中国建设银行，每天等于其它意思，有变动
     * 4    一处定义，多处使用
     * ====================================================
     */


    //V6 独立出来成为枚举版。见PayTypeStrEnum
    public Integer parsePayTypeV6(String payTypeStr)
    {
        return PayTypeStrEnum.parseCode(payTypeStr);
    }












    //V7 枚举只是简单的映射，复杂业务绝对不够用，遇事不决设计模式,引入策略模式
    public Integer parsePayTypeV7(String payTypeStr)
    {
        PayTypeParseContext payTypeParseContext = new PayTypeParseContext();

        switch (payTypeStr)
        {
            case "CCB":payTypeParseContext.setPayTypeParseStrategy(new CCBPayTypeParseStrategy());break;
            //case "ABC":payTypeParseContext.setPayTypeParseStrategy(new ABCPayTypeParseStrategy());break;
            default:return null;
        }
        return payTypeParseContext.parse();
    }








    /**
     *
     * @param payTypeStr
     * @return
     */
    //@Resource
    private PayTypeParseStrategyContainer payTypeParseStrategyContainer = new PayTypeParseStrategyContainer();

    public Integer parsePayTypeV8(String payTypeStr)
    {
        PayTypeStrEnum payTypeStrEnum = PayTypeStrEnum.get(payTypeStr);
        PayTypeParseContext context = new PayTypeParseContext();
        context.setPayTypeStrEnum(payTypeStrEnum);

        System.out.println("context: "+context.parse());


       return payTypeParseStrategyContainer.parse(context);
    }


    private static void StringUtilsisBlankAndisEmpty()
    {
        String nullString = null;
        String emptyString = "";
        String blankString = "   "; // 只包含空格
        String normalString = "Hello, World!";

        System.out.println(StringUtils.isBlank(nullString));    // 输出: true
        System.out.println(StringUtils.isBlank(emptyString));   // 输出: true
        System.out.println(StringUtils.isBlank(blankString));   // 输出: true
        System.out.println(StringUtils.isBlank(normalString));  // 输出: false

        System.out.println();

        System.out.println(StringUtils.isEmpty(nullString));    // 输出: true
        System.out.println(StringUtils.isEmpty(emptyString));   // 输出: true
        System.out.println(StringUtils.isEmpty(blankString));   // 输出: false
        System.out.println(StringUtils.isEmpty(normalString));  // 输出: false
    }







    public static void main(String[] args)
    {
        StringUtilsisBlankAndisEmpty();




        OverDesignDemo test = new OverDesignDemo();

        //System.out.println(test.parsePayTypeV6("CCB"));
        //System.out.println(test.parsePayTypeV7("CCB"));
        System.out.println(test.parsePayTypeV8("CCB"));


    }
}
